package com.template.controller;

import com.template.common.annotation.Authority;
import com.template.common.lang.Const;
import com.template.common.lang.R;
import com.template.common.validgroup.Create;
import com.template.common.validgroup.Menu;
import com.template.common.validgroup.Update;
import com.template.domain.vo.MenuVo;
import com.template.service.SysMenuService;
import com.template.utils.ValidationUtils;
import jakarta.validation.constraints.NotNull;
import lombok.RequiredArgsConstructor;
import org.apache.commons.lang3.StringUtils;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import com.template.domain.entity.SysMenu;

import java.util.*;

/**
 * 控制层。
 *
 * @author dong
 * @since 2023-09-03
 */
@Validated
@RestController
@RequestMapping("/menu")
@RequiredArgsConstructor
public class SysMenuController {

    private final SysMenuService sysMenuService;

    @GetMapping("/keepalive")
    public R<List<String>> getKeepaliveMenu() {
        List<String> names = sysMenuService.getKeepaliveMenu();
        return R.success(names);
    }

    @Authority("sys:menu:add")
    @PostMapping
    public R<String> add(@RequestBody SysMenu sysMenu) {
        Class<?> clazz = getMenuGroup(sysMenu);
        ValidationUtils.validFast(sysMenu, clazz, Create.class);
        // 防止插入空串导致唯一性约束生效
        if (StringUtils.isBlank(sysMenu.getPerms())) {
            sysMenu.setPerms(null);
        }
        sysMenuService.save(sysMenu);
        return R.success();
    }

    @Authority("sys:menu:update")
    @PutMapping
    public R<String> update(@RequestBody SysMenu sysMenu) {
        Class<?> clazz = getMenuGroup(sysMenu);
        ValidationUtils.validFast(sysMenu, clazz, Update.class);
        // 防止插入空串导致唯一性约束生效
        if (StringUtils.isBlank(sysMenu.getPerms())) {
            sysMenu.setPerms(null);
        }
        boolean b = sysMenuService.updateById(sysMenu, false);
        return b ? R.success() : R.fail("该菜单不存在");
    }

    private Class<?> getMenuGroup(SysMenu sysMenu) {
        return switch (sysMenu.getType()) {
            case SysMenu.Type.Catalog -> Menu.Catalog.class;
            case SysMenu.Type.Page -> Menu.Page.class;
            case SysMenu.Type.Button -> Menu.Button.class;
            default -> throw new IllegalArgumentException(Const.Error.PARAMS_INVALID);
        };
    }

    @Authority("sys:menu:remove")
    @DeleteMapping
    public R<String> remove(@NotNull(message = "菜单id为必要参数") Long id) {
        sysMenuService.removeCascadeById(id);
        return R.success();
    }

    @Authority("sys:menu:get")
    @GetMapping("/tree")
    public R<List<MenuVo.Tree>> getTree() {
        List<MenuVo.Tree> menuTree = sysMenuService.getTree();
        return R.success(menuTree);
    }

    @Authority("sys:menu:get")
    @GetMapping("/tree/alive")
    public R<List<MenuVo.Tree>> getAliveTree() {
        List<MenuVo.Tree> menuTree = sysMenuService.getAliveTree();
        return R.success(menuTree);
    }

}
